package com.honghe.system.controller;

import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.honghe.common.annotation.Log;
import com.honghe.common.core.controller.BaseController;
import com.honghe.common.core.domain.AjaxResult;
import com.honghe.common.enums.BusinessType;
import com.honghe.system.domain.BankCustomerCases;
import com.honghe.system.service.IBankCustomerCasesService;
import com.honghe.common.utils.poi.ExcelUtil;
import com.honghe.common.core.page.TableDataInfo;
import com.honghe.common.utils.file.FileUploadUtils;
import com.honghe.common.utils.file.FileUtils;
import com.honghe.common.config.RuoYiConfig;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import org.springframework.util.StringUtils;
import java.util.Map;
import com.honghe.common.utils.Convert;
import java.util.HashMap;
import com.honghe.system.mapper.BankCustomerCasesMapper;
import com.honghe.common.utils.SecurityUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.honghe.common.utils.DateUtils;

/**
 * 客户信息Controller
 * 
 * @author ruoyi
 * @date 2025-04-13
 */
@RestController
@RequestMapping("/system/cases")
public class BankCustomerCasesController extends BaseController
{
    @Autowired
    private IBankCustomerCasesService bankCustomerCasesService;
    
    @Autowired
    private BankCustomerCasesMapper bankCustomerCasesMapper;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 查询客户信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:cases:list')")
    @GetMapping("/list")
    public TableDataInfo list(BankCustomerCases bankCustomerCases)
    {
        startPage();
        List<BankCustomerCases> list = bankCustomerCasesService.selectBankCustomerCasesList(bankCustomerCases);
        TableDataInfo tableDataInfo = getDataTable(list);
        
        // 如果需要公海池统计
        if (bankCustomerCases.getParams() != null && "true".equals(bankCustomerCases.getParams().get("needPoolCount")))
        {
            // 获取总体公海池统计
            List<Map<String, Object>> poolCountsList = bankCustomerCasesService.selectPoolCounts();
            Map<String, Long> poolCounts = new HashMap<>();
            
            // 将List<Map>转换为Map<String, Long>
            for (Map<String, Object> count : poolCountsList) {
                String key = String.valueOf(count.get("key"));
                Object value = count.get("value");
                if (value != null) {
                    if (value instanceof Number) {
                        poolCounts.put(key, ((Number) value).longValue());
                    } else {
                        try {
                            poolCounts.put(key, Long.parseLong(value.toString()));
                        } catch (NumberFormatException e) {
                            logger.error("转换公海池统计数据失败: key={}, value={}", key, value);
                        }
                    }
                }
            }
            tableDataInfo.setPoolCounts(poolCounts);

            // 获取时间段内新增客户统计
            String beginTime = (String) bankCustomerCases.getParams().get("beginTime");
            String endTime = (String) bankCustomerCases.getParams().get("endTime");
            
            String poolType = bankCustomerCases.getPoolType();
            
            logger.info("时间段内新增客户统计参数: beginTime={}, endTime={}, poolType={}", beginTime, endTime, poolType);
            
            if (beginTime != null || endTime != null) {
                List<Map<String, Object>> newCustomerStats = bankCustomerCasesService.selectNewCustomerStats(
                    beginTime, endTime, poolType);
                
                logger.info("时间段内新增客户统计结果: {}", newCustomerStats);
                
                Map<String, Long> periodStats = new HashMap<>();
                for (Map<String, Object> stat : newCustomerStats) {
                    String key = String.valueOf(stat.get("key"));
                    Object value = stat.get("value");
                    if (value != null) {
                        if (value instanceof Number) {
                            periodStats.put(key, ((Number) value).longValue());
                        } else {
                            try {
                                periodStats.put(key, Long.parseLong(value.toString()));
                            } catch (NumberFormatException e) {
                                logger.error("转换时间段统计数据失败: key={}, value={}", key, value);
                            }
                        }
                    }
                }
                tableDataInfo.setPeriodStats(periodStats);
                logger.info("返回时间段统计数据: {}", periodStats);
            }
        }
        return tableDataInfo;
    }

    /**
     * 导出客户信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:cases:export')")
    @Log(title = "客户信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BankCustomerCases bankCustomerCases)
    {
        List<BankCustomerCases> list = bankCustomerCasesService.selectBankCustomerCasesList(bankCustomerCases);
        ExcelUtil<BankCustomerCases> util = new ExcelUtil<BankCustomerCases>(BankCustomerCases.class);
        util.exportExcel(response, list, "客户信息数据");
    }

    /**
     * 获取客户信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:cases:query')")
    @GetMapping(value = "/{caseId}")
    public AjaxResult getInfo(@PathVariable("caseId") Long caseId)
    {
        return success(bankCustomerCasesService.selectBankCustomerCasesByCaseId(caseId));
    }

    /**
     * 新增客户信息
     */
    @PreAuthorize("@ss.hasPermi('system:cases:add')")
    @Log(title = "客户信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BankCustomerCases bankCustomerCases)
    {
        return toAjax(bankCustomerCasesService.insertBankCustomerCases(bankCustomerCases));
    }

    /**
     * 修改客户信息
     */
    @PreAuthorize("@ss.hasPermi('system:cases:edit')")
    @Log(title = "客户信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BankCustomerCases bankCustomerCases)
    {
        // 记录关键字段的值
        logger.info("修改客户信息 - 案件ID: {}", bankCustomerCases.getCaseId());
        logger.info("修改客户信息 - 客户姓名: {}", bankCustomerCases.getCustomerName());
        logger.info("修改客户信息 - 联系电话: {}", bankCustomerCases.getContactPhone());
        
        return toAjax(bankCustomerCasesService.updateBankCustomerCases(bankCustomerCases));
    }

    /**
     * 删除客户信息
     */
    @PreAuthorize("@ss.hasPermi('system:cases:remove')")
    @Log(title = "客户信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{caseIds}")
    public AjaxResult remove(@PathVariable Long[] caseIds)
    {
        return toAjax(bankCustomerCasesService.deleteBankCustomerCasesByCaseIds(caseIds));
    }

    /**
     * 下载文件
     */
    @PreAuthorize("@ss.hasPermi('system:cases:download')")
    @GetMapping("/download-file")
    public void downloadFile(@RequestParam("filePath") String filePath, HttpServletResponse response) throws IOException {
        try {
            String fullPath = RuoYiConfig.getProfile() + "/cases/" + filePath;
            File file = new File(fullPath);
            if (!file.exists()) {
                throw new IOException("文件不存在");
            }
            
            // 获取原始文件名
            String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
            
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + 
                URLEncoder.encode(fileName, "UTF-8"));
            
            FileUtils.writeBytes(fullPath, response.getOutputStream());
        } catch (Exception e) {
            throw new IOException(e.getMessage(), e);
        }
    }

    /**
     * 上传文件
     */
    @PreAuthorize("@ss.hasPermi('system:cases:upload')")
    @Log(title = "客户信息", businessType = BusinessType.UPDATE)
    @PostMapping("/upload")
    public AjaxResult uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            String filePath = FileUploadUtils.upload(file);
            return AjaxResult.success("上传成功", filePath);
        } catch (Exception e) {
            return AjaxResult.error("上传失败：" + e.getMessage());
        }
    }

    /**
     * 设置案件经办人
     */
    @PreAuthorize("@ss.hasPermi('system:cases:handler')")
    @Log(title = "客户信息", businessType = BusinessType.UPDATE)
    @PutMapping("/handler")
    public AjaxResult setHandler(@RequestBody BankCustomerCases bankCustomerCases)
    {
        // 只更新经办人字段
        BankCustomerCases updateCase = new BankCustomerCases();
        updateCase.setCaseId(bankCustomerCases.getCaseId());
        updateCase.setHandlerUser(bankCustomerCases.getHandlerUser());
        return toAjax(bankCustomerCasesService.updateBankCustomerCases(updateCase));
    }

    /**
     * 分配客户到经办人
     */
    @PreAuthorize("@ss.hasPermi('system:cases:edit')")
    @Log(title = "客户分配", businessType = BusinessType.UPDATE)
    @PutMapping("/assign")
    public AjaxResult assign(@RequestBody Map<String, Object> params)
    {
        Long[] ids = Convert.toLongArray(params.get("ids"));
        String handlerUser = Convert.toStr(params.get("handlerUser"));
        return toAjax(bankCustomerCasesService.assignCases(ids, handlerUser, getUsername()));
    }

    /**
     * 更新公海池信息
     */
    @PreAuthorize("@ss.hasPermi('system:cases:edit')")
    @Log(title = "更新公海池", businessType = BusinessType.UPDATE)
    @PutMapping("/pool")
    public AjaxResult updatePool(@RequestBody Map<String, Object> params)
    {
        Long[] ids = Convert.toLongArray(params.get("ids"));
        String poolType = Convert.toStr(params.get("poolType"));
        String caseHandler = Convert.toStr(params.get("caseHandler"));
        String handlerUser = Convert.toStr(params.get("handlerUser"));
        return toAjax(bankCustomerCasesService.updateCasesPool(ids, poolType, caseHandler, handlerUser, getUsername()));
    }

    /**
     * 预览文件
     */
    @PreAuthorize("@ss.hasPermi('system:cases:query')")
    @GetMapping("/preview-file")
    public void previewFile(@RequestParam("filePath") String filePath, HttpServletResponse response) throws IOException {
        try {
            String fullPath = RuoYiConfig.getProfile() + "/" + filePath;
            logger.info("预览文件路径: {}", fullPath);
            
            File file = new File(fullPath);
            if (!file.exists()) {
                logger.error("文件不存在: {}", fullPath);
                throw new IOException("文件不存在");
            }
            
            // 获取文件名和扩展名
            String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
            String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
            
            // 根据文件类型设置不同的Content-Type
            String contentType = "application/octet-stream";
            
            // 图片类型
            if (fileExt.equals("jpg") || fileExt.equals("jpeg")) {
                contentType = "image/jpeg";
            } else if (fileExt.equals("png")) {
                contentType = "image/png";
            } else if (fileExt.equals("gif")) {
                contentType = "image/gif";
            } else if (fileExt.equals("bmp")) {
                contentType = "image/bmp";
            } 
            // PDF类型
            else if (fileExt.equals("pdf")) {
                contentType = "application/pdf";
            }
            
            logger.info("文件类型: {}", contentType);
            
            // 设置响应头
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            // 允许跨域访问
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
            // 设置缓存控制
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "0");
            
            // 写入文件内容
            FileUtils.writeBytes(fullPath, response.getOutputStream());
            logger.info("文件预览成功: {}", fileName);
        } catch (Exception e) {
            logger.error("文件预览失败", e);
            response.setContentType("text/plain;charset=UTF-8");
            response.getWriter().write("文件预览失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新关联人信息
     */
    @PreAuthorize("@ss.hasPermi('system:cases:edit')")
    @Log(title = "更新关联人信息", businessType = BusinessType.UPDATE)
    @PutMapping("/contact-persons")
    public AjaxResult updateContactPersons(@RequestBody Map<String, Object> params) {
        try {
            // 获取参数
            String caseId = Convert.toStr(params.get("caseId"));
            String contactPersonName = Convert.toStr(params.get("contactPersonName"));
            String contactPersonPhone = Convert.toStr(params.get("contactPersonPhone"));
            String contactPersonIdCard = Convert.toStr(params.get("contactPersonIdCard"));
            
            if (StringUtils.isEmpty(caseId)) {
                return AjaxResult.error("客户ID不能为空");
            }
            
            // 记录日志
            logger.info("更新关联人信息 - 案件ID: {}", caseId);
            logger.info("更新关联人信息 - 关联人姓名JSON: {}", contactPersonName);
            logger.info("更新关联人信息 - 关联人电话JSON: {}", contactPersonPhone);
            logger.info("更新关联人信息 - 关联人身份证号码JSON: {}", contactPersonIdCard);
            
            // 检查JSON格式并验证是否为数组
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                // 验证JSON格式是否正确
                objectMapper.readTree(contactPersonName);
                objectMapper.readTree(contactPersonPhone);
                objectMapper.readTree(contactPersonIdCard);
                
                try {
                    List<String> names = objectMapper.readValue(contactPersonName, List.class);
                    List<String> phones = objectMapper.readValue(contactPersonPhone, List.class);
                    List<String> idCards = objectMapper.readValue(contactPersonIdCard, List.class);
                    
                    logger.info("解析后的关联人数量 - 姓名: {}, 电话: {}, 身份证号码: {}", 
                        names.size(), phones.size(), idCards.size());
                    
                    // 如果数组为空，确保使用标准的空数组格式
                    if (names.isEmpty() && phones.isEmpty() && idCards.isEmpty()) {
                        contactPersonName = "[]";
                        contactPersonPhone = "[]";
                        contactPersonIdCard = "[]";
                    }
                } catch (Exception e) {
                    logger.error("解析关联人数组内容失败", e);
                    // 不中断处理，因为前面已经验证了基本的数组格式
                }
            } catch (Exception e) {
                logger.error("JSON格式错误", e);
                return AjaxResult.error("关联人信息格式错误: " + e.getMessage());
            }
            
            // 创建更新对象
            BankCustomerCases updateCase = new BankCustomerCases();
            updateCase.setCaseId(caseId);
            updateCase.setContactPersonName(contactPersonName);
            updateCase.setContactPersonPhone(contactPersonPhone);
            updateCase.setContactPersonIdCard(contactPersonIdCard);
            updateCase.setUpdateBy(getUsername());
            updateCase.setUpdateTime(DateUtils.getNowDate());
            
            // 执行更新
            int rows = bankCustomerCasesService.updateBankCustomerCases(updateCase);
            return rows > 0 ? AjaxResult.success() : AjaxResult.error("更新关联人信息失败");
        } catch (Exception e) {
            logger.error("更新关联人信息异常", e);
            return AjaxResult.error("更新关联人信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除关联人信息
     */
    @PreAuthorize("@ss.hasPermi('system:cases:edit')")
    @Log(title = "删除关联人信息", businessType = BusinessType.UPDATE)
    @PutMapping("/delete-contact-person")
    public AjaxResult deleteContactPerson(@RequestBody Map<String, Object> params) {
        try {
            // 获取参数
            String caseId = Convert.toStr(params.get("caseId"));
            
            if (StringUtils.isEmpty(caseId)) {
                return AjaxResult.error("客户ID不能为空");
            }
            
            // 获取当前案件信息
            Long caseIdLong = Convert.toLong(caseId);
            BankCustomerCases currentCase = bankCustomerCasesService.selectBankCustomerCasesByCaseId(caseIdLong);
            if (currentCase == null) {
                return AjaxResult.error("未找到对应的客户信息");
            }
            
            // 获取更新后的关联人数据
            String contactPersonName = Convert.toStr(params.get("contactPersonName"));
            String contactPersonPhone = Convert.toStr(params.get("contactPersonPhone"));
            String contactPersonIdCard = Convert.toStr(params.get("contactPersonIdCard"));
            
            // 记录日志
            logger.info("删除关联人信息 - 案件ID: {}", caseId);
            logger.info("删除关联人后的数据 - 关联人姓名JSON: {}", contactPersonName);
            logger.info("删除关联人后的数据 - 关联人电话JSON: {}", contactPersonPhone);
            logger.info("删除关联人后的数据 - 关联人身份证号码JSON: {}", contactPersonIdCard);
            
            // 验证JSON格式
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                // 验证JSON格式是否正确
                objectMapper.readTree(contactPersonName);
                objectMapper.readTree(contactPersonPhone);
                objectMapper.readTree(contactPersonIdCard);
            } catch (Exception e) {
                logger.error("JSON格式错误", e);
                return AjaxResult.error("关联人信息格式错误: " + e.getMessage());
            }
            
            // 创建更新对象
            BankCustomerCases updateCase = new BankCustomerCases();
            updateCase.setCaseId(caseId);
            updateCase.setContactPersonName(contactPersonName);
            updateCase.setContactPersonPhone(contactPersonPhone);
            updateCase.setContactPersonIdCard(contactPersonIdCard);
            updateCase.setUpdateBy(getUsername());
            updateCase.setUpdateTime(DateUtils.getNowDate());
            
            // 执行更新
            int rows = bankCustomerCasesService.updateBankCustomerCases(updateCase);
            return rows > 0 ? AjaxResult.success() : AjaxResult.error("删除关联人信息失败");
        } catch (Exception e) {
            logger.error("删除关联人信息异常", e);
            return AjaxResult.error("删除关联人信息失败: " + e.getMessage());
        }
    }
}
